/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spotifynews;

import com.sun.jna.Native;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class ProgramLoopThread extends Thread {

    private SpotifyNews gui;

    private volatile boolean started = false;
    private volatile boolean stopped = false;
    private volatile boolean resume;

    private W32API.HWND hwnd;

    int APPCOMMAND      = 0x0319;

    int CMD_NONE        = 0;
    int CMD_PLAYPAUSE   = 917504;
    int CMD_MUTE        = 524288;
    int CMD_VOLUMEDOWN  = 589824;
    int CMD_VOLUMEUP    = 655360;
    int CMD_STOP        = 851968;
    int CMD_PREVIOUS    = 786432;
    int CMD_NEXT        = 720896;

    private boolean spotifyIsPlaying = false;
    private boolean goPlayNewsNow = false;
    private boolean goPlayEveryHour = false;
    private String lastNewsPlayed = "";
    private boolean continueAfterNews = false;
    private boolean continuePlaying = false;
    private NOSHeadlinesPlayer NOSHeadlinesPlayer;

    public ProgramLoopThread(SpotifyNews gui) {
        this.gui = gui;
        NOSHeadlinesPlayer = new NOSHeadlinesPlayer();
    }

    public void run() {
        String currentTitle = "";
        while (!stopped) {

            //System.out.println("nos: "+NOSHeadlinesPlayer.isPlaying());
            //System.out.println("spotify: "+spotifyIsPlaying);
            //System.out.println("continue: "+continuePlaying);

            if(findSpotifyWindow()){
                byte[] windowTitle = new byte[512];
                User32.INSTANCE.GetWindowTextA(hwnd, windowTitle, 512);
                boolean isPlayingNow = Native.toString(windowTitle).contains("-");

                //Don't play the news after spotify was paused
                if(isPlayingNow && !spotifyIsPlaying){
                    lastNewsPlayed = currentHour();
                }

                spotifyIsPlaying = isPlayingNow;

                if(spotifyIsPlaying && !currentTitle.equals(Native.toString(windowTitle))){
                    String prevTitle = currentTitle;
                    currentTitle = Native.toString(windowTitle);
                    //System.out.println(currentTitle);
                    gui.setStatus("Now playing: "+currentTitle);
                    
                    if(!prevTitle.isEmpty() && !currentTitle.isEmpty()){
                        //Nieuw nummer!
                        if(goPlayNewsNow){
                            User32.INSTANCE.SendMessage(hwnd, APPCOMMAND, 0, CMD_PLAYPAUSE);
                            playNews();
                            continueAfterNews = true;
                            goPlayNewsNow = false;
                        } else if(goPlayEveryHour && !lastNewsPlayed.equals(currentHour())){
                            User32.INSTANCE.SendMessage(hwnd, APPCOMMAND, 0, CMD_PLAYPAUSE);
                            playNews();
                            continueAfterNews = true;
                            lastNewsPlayed = currentHour();
                        }
                    }
                } else if(!spotifyIsPlaying && (continuePlaying || NOSHeadlinesPlayer.isDone())){
                    stopNews();
                    continuePlaying = false;
                    if(continueAfterNews){
                        gui.setStatus("Now playing: "+currentTitle);
                        User32.INSTANCE.SendMessage(hwnd, APPCOMMAND, 0, CMD_PLAYPAUSE);
                        continueAfterNews = false;
                    }
                } else if(!spotifyIsPlaying && goPlayNewsNow){
                    playNews();
                    continueAfterNews = false;
                    goPlayNewsNow = false;
                } else {
                    if(!spotifyIsPlaying && !NOSHeadlinesPlayer.isPlaying()){
                        gui.setStatus("Spotify is gepauzeerd, NOS Heaslines zal niet automatisch worden afgespeeld.");
                    } else if(spotifyIsPlaying && NOSHeadlinesPlayer.isPlaying() && !NOSHeadlinesPlayer.isStopping()) {
                        gui.setStatus("Bezig met het laatste NOS Headlines aan het afspelen.");
                    }
                }
            }

            
            try {
                sleep(100);
            } catch (InterruptedException expected) {
                if (!stopped) {
                    synchronized (this) {
                        try {
                            //System.out.println("Loop paused...");
                            while (!resume) {
                                this.wait();
                            }
                        } catch (InterruptedException stopping) {
                        }
                    }
                }
            }
        }
    }

    private boolean findSpotifyWindow(){
        this.hwnd = User32.INSTANCE.FindWindow("SpotifyMainWindow", null);

        if(this.hwnd==null){
            gui.setStatus("Spotify is niet gevonden, is Spotify wel opgestart?");
        }
        return (this.hwnd!=null);
    }

    public String currentHour() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh");
        return sdf.format(cal.getTime());
    }

    public void playNews() {
        //System.out.println("playNews!");
        NOSHeadlinesPlayer = new NOSHeadlinesPlayer();
        NOSHeadlinesPlayer.start();
        gui.setStatus("Ga de laatste NOS Headlines afspelen...");
    }

    public void stopNews() {
        if(NOSHeadlinesPlayer.isPlaying()){
            NOSHeadlinesPlayer.stopNews();
        }
    }

    public void startLoop() {
        started = true;
        this.start();
    }

    public void stopLoop() {
        stopped = true;
        this.interrupt();
    }

    public void pauseLoop() {
        resume = false;
        this.interrupt();
    }

    public void resumeLoop() {
        resume = true;
        synchronized (this) {
            this.notify();
        }
    }

    public boolean isPaused() {
        return !resume;
    }

    public boolean isStarted() {
        return started && !stopped;
    }

    public void setPlayNewsEveryHour(boolean playEveryHour){
        if(playEveryHour){
            lastNewsPlayed = currentHour();
        }
        goPlayEveryHour = playEveryHour;
    }

    public void goPlayNews() {
        goPlayNewsNow = true;
    }

    public void continuePlaying() {
        if(NOSHeadlinesPlayer.isPlaying()){
            continuePlaying = true;
        }
    }
}
